package com.game.battle.service.battle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.game.battle.common.map.BattleMap;
import com.game.battle.config.DungeonConditionConfig;
import com.game.battle.config.XMLTemplateService;
import com.game.core.service.PublicService;
import com.game.dbpersistence.game.entity.ItemEntity;
import com.game.message.proto.battle.BattleProtoBuf.MAchieveCondition;

public class AchievementService extends PublicService{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private BattleMap battleMap;
	
	public static enum AchievementType {
		/* 通关时玩家所用回合数低于限定值获得成就奖励 */
		BattleRound(301),
		/* 通关时玩家剩余血量百分比达到限定值获得成就奖励 */
		SelfHPPercent(302),
		/* 击杀怪物总伤害达到要求值获得成就奖励*/
		TotalRoundsDamage(303),
		/* 某场战斗中击杀某个怪物个数达到要求值获得成就奖励*/
		TotalRoundsKillMonsterCount(304),
		/* 单回合内对怪物造成伤害达到要求值获得成就奖励*/
		SingleRoundDamage(305),
		/* 某回合战斗中击杀某个怪物个数达到要求值获得成就奖励 */
		SingleRoundKillMonsterCount(306),
		/* 不使用指定某类武器通关获得成就奖励 */
		WithoutWeapon(307),
		/* 护送或者护卫目标剩余血量百分比*/
		//ProtectNPCHPPercent(308),
		/* 多人副本通过时死亡的人次少于限定值获得成就奖励*/
		TeamPlayerDeadCount(309),
		/* 副本通关时击败指定id怪物获得成就奖励*/
		KillSpecificMonster(310),
		/* 使用指定某类武器通关获得成就奖励 */
		WithWeapon(311),;
		
		private int value;
		
		private AchievementType(int value) {
			this.value = value;
		}
		
		public int getValue() {
			return value;
		}
		
	}
	/**
	 * 成就类型与成就id索引
	 */
	public HashMap<Integer, List<String>>  achievementTypeMap = new HashMap<>();
	
	/**
	 * 当前关卡的成就配置 id : config
	 */
	public HashMap<String, DungeonConditionConfig> achievementMap = new HashMap<>();
	/**
	 * 当前关卡的成就配置 id : 和奖励物品ID及数量
	 */
	public HashMap<String, HashMap<String, String>> achievementItemMap = new HashMap<>();
	/**
	 * 当前用户各成就的完成数值 account : {id : amount}
	 */
	public HashMap<String, HashMap<String, String>> playerAchievementMap = new HashMap<>();
	
	/**
	 * 当前用户完成的成就列表 account : {id}
	 */
	public HashMap <String, List<String>> playerCompleteAchievementListMap = new HashMap<>(); 

	
	public AchievementService(BattleMap battleMap) {
		this.battleMap = battleMap;
		String dungeonConfigCondition = battleMap.dungeonConfig.getCondition();
		String[] conditionList = dungeonConfigCondition.split("\\|");
		for (String dungeonConfig : conditionList) {
			String[] params = dungeonConfig.split(",");
			String conditionId = params[0];
			
			String itemId = params[1];
			String itemCnt = params[2];
			HashMap<String, String> item = new HashMap<String, String>();
			item.put(itemId, itemCnt);
			achievementItemMap.put(conditionId, item);
			
			DungeonConditionConfig conditionConfig = XMLTemplateService.dungeonConditionConfigMap.get(Integer.parseInt(conditionId));
			achievementMap.put(conditionId, conditionConfig);
			if (achievementTypeMap.containsKey(conditionConfig.getType())) {
				achievementTypeMap.get(conditionConfig.getType()).add(conditionId);
			} else {
				List<String> achievementIdList = new ArrayList<>();
				achievementIdList.add(conditionId);
				achievementTypeMap.put(conditionConfig.getType(), achievementIdList);
			}
		}
		for (String account : battleMap.getPlayers(BattleMap.realStage).keySet()) {
			HashMap<String, String> tmpAchievementMap = new HashMap<>();
			playerAchievementMap.put(account, tmpAchievementMap);
		}
	}

	/**
	 * 成就系统触发点
	 * @param checkAchievement
	 * @param account
	 * @param param
	 */
	public void checkAchievement(AchievementType checkAchievement, String account, String param) {
		// 当前关卡没有该类型成就
		if (!achievementTypeMap.keySet().contains(checkAchievement.getValue())) {
			return;
		}
		// 记录成就
		HashMap<String, String> tmpMap = playerAchievementMap.get(account);
		switch (checkAchievement) {
		//参数 the more the better
		case BattleRound:
		//case ProtectNPCHPPercent:
		case SelfHPPercent:
		case SingleRoundDamage:
		case TeamPlayerDeadCount:
			// 不存在该成就记录或数值大于该成就已存记录，则更新
			for (String achievementId : achievementTypeMap.get(checkAchievement.getValue())) {
				if (tmpMap.get(achievementId) == null || Integer.parseInt(tmpMap.get(achievementId)) < Integer.parseInt(param)) {
					tmpMap.put(achievementId, param);
				}
			}
			
			break;
			
		// 累计型
		case TotalRoundsDamage:
			for (String achievementId : achievementTypeMap.get(checkAchievement.getValue())) {
				if (tmpMap.get(achievementId) == null) {
					tmpMap.put(achievementId, param);
				} else {
					tmpMap.put(achievementId, Integer.toString(Integer.parseInt(tmpMap.get(achievementId)) + Integer.parseInt(param)));
				}
			}
			break;
		case SingleRoundKillMonsterCount:
		case TotalRoundsKillMonsterCount:
			//要加入怪物ID的判断
			for (String achievementId : achievementTypeMap.get(checkAchievement.getValue())) {
				String condition = achievementMap.get(achievementId).getCondition();
				if((condition!=null) && (!condition.isEmpty())) {
					String monsterId = condition.split(",")[0];
					if((monsterId!=null) && (!monsterId.isEmpty()) && monsterId.equals(param)) {
						if (tmpMap.get(achievementId) == null) {
							tmpMap.put(achievementId, param);
						} else {
							tmpMap.put(achievementId, Integer.toString(Integer.parseInt(tmpMap.get(achievementId)) + Integer.parseInt(param)));
						}
					}
				}
			}
			break;
		// 杀死指定怪物，参数为怪物id
		case KillSpecificMonster:
			for (String achievementId : achievementTypeMap.get(checkAchievement.getValue())) {
				if (tmpMap.get(achievementId) == null && achievementMap.get(achievementId).getCondition().equals(param)) {
					tmpMap.put(achievementId, param);
				}
			}
			break;
		default:
			break;
		
		}
	}
	
	/**
	 * 成就系统结算点
	 * @return
	 */
	public HashMap<String, List<String>> settleAchievement() {
		for (String account : battleMap.getPlayers(BattleMap.realStage).keySet()) {
			List<String> achieveList = new ArrayList<>();
			for (Map.Entry<String, String> tmpEntry : this.playerAchievementMap.get(account).entrySet()) {
				if (achieveList.contains(tmpEntry.getKey())) {
					continue;
				}
				int conditionType = achievementMap.get(tmpEntry.getKey()).getType();
				if (conditionType == AchievementType.SingleRoundDamage.getValue() ||
					conditionType == AchievementType.TotalRoundsDamage.getValue() ||
					//conditionType == AchievementType.ProtectNPCHPPercent.getValue()||
					conditionType == AchievementType.SelfHPPercent.getValue()) {
					if (Integer.parseInt(tmpEntry.getValue()) > Integer.parseInt(achievementMap.get(tmpEntry.getKey()).getCondition())) {
						achieveList.add(tmpEntry.getKey());
					}
				}
				if (conditionType == AchievementType.BattleRound.getValue() ||
					conditionType == AchievementType.TeamPlayerDeadCount.getValue()) {
					if (Integer.parseInt(tmpEntry.getValue()) < Integer.parseInt(achievementMap.get(tmpEntry.getKey()).getCondition())) {
						achieveList.add(tmpEntry.getKey());
					}
				}
				else if (conditionType == AchievementType.SingleRoundKillMonsterCount.getValue() || 
						conditionType == AchievementType.TotalRoundsKillMonsterCount.getValue() ) {
					String condition = achievementMap.get(tmpEntry.getKey()).getCondition();
					if((condition!=null) && (!condition.isEmpty())) {
						String monsterCounts = condition.split(",")[1];
						if (Integer.parseInt(tmpEntry.getValue()) > Integer.parseInt(monsterCounts)) {
							achieveList.add(tmpEntry.getKey());
						}
					}
				}
				else if (conditionType == AchievementType.KillSpecificMonster.getValue()) {
					if (tmpEntry.getValue().equals(achievementMap.get(tmpEntry.getKey()).getCondition())) {
						achieveList.add(tmpEntry.getKey());
					}
				}
			}
			playerCompleteAchievementListMap.put(account, achieveList);
		}	
		return playerCompleteAchievementListMap;
	}
	
	public HashMap<String, HashMap<String, String>> settleAchievementReward() {
		HashMap <String, HashMap<String, String>> completeAchievementItemMap = new HashMap<>(); 
		for (Map.Entry<String, List<String>> entry : this.playerCompleteAchievementListMap.entrySet()) {
			HashMap<String, String> itemMap = new HashMap<String, String>();
			for (String condition : entry.getValue()) {
				HashMap<String, String>value = new HashMap<>();
				value = achievementItemMap.get(condition);
				for(String key : value.keySet()) {
					if(itemMap.containsKey(key)){
						itemMap.put(key, Integer.toString((Integer.parseInt(value.get(key)) + Integer.parseInt(itemMap.get(key)))));
					}else {
						itemMap.put(key, value.get(key));
					}
				}
			}
			completeAchievementItemMap.put(entry.getKey(), itemMap);
		}
		return completeAchievementItemMap;
	}
	
	public List<MAchieveCondition.Builder> getAchieveConditionBuilderList() {
		List<MAchieveCondition.Builder> builderList = new ArrayList<>();
		for (Map.Entry<String, List<String>> entry : playerCompleteAchievementListMap.entrySet()) {
			MAchieveCondition.Builder builder = MAchieveCondition.newBuilder();
			builder.setAccount(entry.getKey());
			for (String tmpCondition : entry.getValue()) {
				builder.addCondition(tmpCondition);
			}
			builderList.add(builder);
		}
		return builderList;
	}
}
